package com.springbootbase.springbootproject.service.impl;

import com.springbootbase.springbootproject.mapper.*;
import com.springbootbase.springbootproject.pojo.*;
import com.springbootbase.springbootproject.service.recommendationService;
import com.springbootbase.springbootproject.utils.RulesRecommend;
import com.springbootbase.springbootproject.utils.recommend;
import org.apache.tika.exception.TikaException;
import org.mybatis.logging.Logger;
import org.mybatis.logging.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;

@Service
public class recommendationServiceImpl implements recommendationService {

    @Autowired
    private recommendationMapper recommendationMapper;
    @Autowired
    private RecommendationcontactMapper recommendationcontactMapper;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private TeacherMapper teacherMapper;
    @Autowired
    private UserMapper userMapper;
    private static final Logger logger = LoggerFactory.getLogger(recommendationServiceImpl.class);
    private String nameById;

    @Override
    public Recommendation getRecommendSet(Long id) {
       Recommendation recommendation =  recommendationMapper.getSet(id);
       return recommendation;
    }

    @Override
    public void updateSet(Recommendation recommendation) {
        recommendationMapper.updateSet(recommendation);
    }

    @Override
    public ListResponse getRecommendList(Long id, int pageSize, int pageNum) {
        ListResponse listResponse = null;
        String type =  userMapper.getUserTypeById(id);
        ArrayList<Teacher> teacherArrayList = new ArrayList<>();
        ArrayList<Student> studentArrayList = new ArrayList<>();
        ArrayList<RecommendList> recommendListArrayList = null;
        if (Objects.equals(type, "student")){
            recommendListArrayList = recommendationMapper.getStudentList(id);
            for(RecommendList recommendList : recommendListArrayList){
                String name = teacherMapper.getNameById(recommendList.getTeacherId());
                Teacher teacher = teacherMapper.findById(recommendList.getTeacherId());
                teacher.setName(name);
                teacher.setStatus(recommendList.getStatus());
                teacherArrayList.add(teacher);
            }
            int total = teacherArrayList.size();
            int startIndex = (pageNum-1)*pageSize;
            int endIndex = startIndex + pageSize;
            if (endIndex>total) endIndex=total;
            List<Teacher> teacherList =  teacherArrayList.subList(startIndex,endIndex);
            listResponse = new ListResponse(teacherList,total);

        }else if (Objects.equals(type, "teacher")){
            recommendListArrayList = recommendationMapper.getTeacherList(id);
            for(RecommendList recommendList : recommendListArrayList){
                String name = studentMapper.getNameById(recommendList.getStudentId());
                Student student = studentMapper.findById(recommendList.getStudentId());
                student.setName(name);
                student.setStatus(recommendList.getStatus());
                studentArrayList.add(student);
            }
            int total = studentArrayList.size();
            int startIndex = (pageNum-1)*pageSize;
            int endIndex = startIndex + pageSize;
            if (endIndex>total) endIndex=total;
            List<Student> students = studentArrayList.subList(startIndex,endIndex);
            listResponse = new ListResponse(students,total);
        }
        return listResponse;

    }

    @Override
    public List<List> getRecommendForStudent(Long id, String userType, double departmentSet, double searchWaySet, double hobbySet) throws TikaException, IOException {
        List<List> recommendList = new ArrayList<>();
        List<Teacher> ruleRecommendList = new ArrayList<>();
        List<Teacher> userRecommendList = new ArrayList<>();
        Student students = studentMapper.getStudent(id);
        List<Student> students1 = studentMapper.getStudentList();
        List<Teacher> teachers = studentMapper.getTeacherList();
        RulesRecommend rulesRecommend = new RulesRecommend(students1,teachers);
//        基于规则的推荐
        Map<Long,Teacher>  ruleRecommend = rulesRecommend.recommendTeacher(students,departmentSet,searchWaySet,hobbySet);
        ArrayList<Recommendationcontact> list = recommendationcontactMapper.getListForRecommend();
        recommend recommends = new recommend(list,userType);
        for (Map.Entry<Long,Teacher> entry : ruleRecommend.entrySet()) {
            int i = recommendationcontactMapper.countContact(id,entry.getKey());
            if (i==0 && entry.getValue().getSimilarity()>0) {
                String name = teacherMapper.getNameById(entry.getValue().getId());
                entry.getValue().setName(name);
                ruleRecommendList.add(entry.getValue());
            }
        }
        ruleRecommendList.sort((i1, i2) -> {
            int priceComparison = Double.compare(i2.getSimilarity(), i1.getSimilarity());
            if (priceComparison != 0) {
                return priceComparison; // 如果price不同，直接返回price的比较结果
            } else {
                return Double.compare(i2.getHindex(), i1.getHindex()); // 如果price相同，比较hindex
            }
        });
        recommendList.add(ruleRecommendList);
//            基于内容的推荐
            Map<Long,Double> map = recommends.userBasedRecommendForStudent(id);
            for (Map.Entry<Long,Double> entry : map.entrySet()){
                Teacher teacher = teacherMapper.findById(entry.getKey());
                String name = teacherMapper.getNameById(entry.getKey());
                teacher.setSimilarity(entry.getValue());
                teacher.setName(name);
                userRecommendList.add(teacher);
            }
        userRecommendList.sort((i1, i2) -> {
            int priceComparison = Double.compare(i2.getSimilarity(), i1.getSimilarity());
            if (priceComparison != 0) {
                return priceComparison; // 如果price不同，直接返回price的比较结果
            } else {
                return Double.compare(i2.getHindex(), i1.getHindex()); // 如果price相同，比较hindex
            }
        });
            recommendList.add(userRecommendList);
        return recommendList;
    }


//    public List<Teacher> getRecommendForStudent2(Long id, String userType, double departmentSet, double searchWaySet, double hobbySet) {
//        int count = recommendationcontactMapper.countStudentContact(id);
//        List<Teacher> recommendList = new ArrayList<>();
//        Student students = studentMapper.getStudent(id);
//        List<Student> students1 = studentMapper.getStudentList();
//        List<Teacher> teachers = studentMapper.getTeacherList();
//        RulesRecommend rulesRecommend = new RulesRecommend(students1,teachers);
////        基于规则的推荐
//        Map<Long,Teacher>  ruleRecommend = rulesRecommend.recommendTeacher(students,departmentSet,searchWaySet,hobbySet);
//        ArrayList<Recommendationcontact> list = recommendationcontactMapper.getListForRecommend();
//        recommend recommends = new recommend(list,userType);
//        //        如果是0次表示不需要基于内容的
//        if (count==0){
//            List<Map.Entry<Long,Teacher>> entries = new ArrayList<>(ruleRecommend.entrySet());
//            for (Map.Entry<Long,Teacher> entry : entries) {
//                recommendList.add(entry.getValue());
//            }
//        }else {
////            基于内容的推荐
//            Map<Long,Double> map = recommends.userBasedRecommendForStudent(id);
//            Map<Long,Teacher> teacherMap = new HashMap<>();
//            List<Map.Entry<Long,Double>> entries = new ArrayList<>(map.entrySet());
//            for (Map.Entry<Long,Double> entry : entries){
//                Teacher teacher = teacherMapper.findById(entry.getKey());
//                teacher.setSimilarity(entry.getValue());
//                teacherMap.put(entry.getKey(),teacher);
//            }
//            Map<Long,Teacher> teacherMap1 = mergeTeacherMap(ruleRecommend,teacherMap);
//            for (Map.Entry<Long,Teacher> entry : teacherMap1.entrySet()){
//                recommendList.add(entry.getValue());
//            }
//        }
//        recommendList.sort((i1, i2) -> {
//            int priceComparison = Double.compare(i2.getSimilarity(), i1.getSimilarity());
//            if (priceComparison != 0) {
//                return priceComparison; // 如果price不同，直接返回price的比较结果
//            } else {
//                return Double.compare(i2.getHindex(), i1.getHindex()); // 如果price相同，比较hindex
//            }
//        });
//        return recommendList;
//    }
//    先输入基于内容 再输入 基于用户  0.4，0.6
    public  Map<Long, Teacher> mergeTeacherMap(Map<Long, Teacher> map1, Map<Long, Teacher> map2) {
        Map<Long, Teacher> mergedMap = new HashMap<>(map1); // 将map1的所有条目复制到mergedMap中

        // 遍历map2的每一个条目
        for (Map.Entry<Long, Teacher> entry : map2.entrySet()) {
            Long key = entry.getKey();
            Teacher teacher = entry.getValue();

            // 如果mergedMap中已经存在这个键，则相加similarity
            if (mergedMap.containsKey(key)) {
                Teacher existingTeacher = mergedMap.get(key);
                existingTeacher.setSimilarity(existingTeacher.getSimilarity()*0.4 + 0.6*teacher.getSimilarity());
            } else {
                // 如果不存在，则直接插入到mergedMap中
                mergedMap.put(key, teacher);
            }
        }
        return mergedMap;
    }
    public static Map<Long, Student> mergeStudentMap(Map<Long, Student> map1, Map<Long, Student> map2) {
        Map<Long, Student> mergedMap = new HashMap<>(map1); // 将map1的所有条目复制到mergedMap中

        // 遍历map2的每一个条目
        for (Map.Entry<Long, Student> entry : map2.entrySet()) {
            Long key = entry.getKey();
            Student student = entry.getValue();

            // 如果mergedMap中已经存在这个键，则相加similarity
            if (mergedMap.containsKey(key)) {
                Student existingStudent = mergedMap.get(key);
                existingStudent.setSimilarity(existingStudent.getSimilarity()*0.4 + 0.6*student.getSimilarity());
            } else {
                // 如果不存在，则直接插入到mergedMap中
                mergedMap.put(key, student);
            }
        }

        return mergedMap;
    }
    @Override
    public List<List> getRecommendForTeacher(Long id, String userType, double departmentSet, double searchWaySet, double hobbySet) throws TikaException, IOException {
        List<List> recommendList = new ArrayList<>();
        List<Student> ruleRecommendList = new ArrayList<>();
        List<Student> userRecommendList = new ArrayList<>();
        Teacher teacher = teacherMapper.findById(id);
        List<Student> students1 = studentMapper.getStudentList();
        List<Teacher> teachers = studentMapper.getTeacherList();

//        基于规则的推荐
        RulesRecommend rulesRecommend = new RulesRecommend(students1,teachers);
        Map<Long,Student>  ruleRecommend = rulesRecommend.recommendStudent(teacher,departmentSet,searchWaySet,hobbySet);
        for (Map.Entry<Long,Student> entry : ruleRecommend.entrySet()) {
            int i = recommendationcontactMapper.countContact(entry.getKey(),id);
            if (i==0 && entry.getValue().getSimilarity()>0){
                String name = studentMapper.getNameById(entry.getValue().getId());
                entry.getValue().setName(name);
                ruleRecommendList.add(entry.getValue());
            }
        }
        ruleRecommendList.sort((i1, i2) -> {
            int priceComparison = Double.compare(i2.getSimilarity(), i1.getSimilarity());
            if (priceComparison != 0) {
                return priceComparison; // 如果price不同，直接返回price的比较结果
            } else {
                return Long.compare(i1.getRank(), i2.getRank()); // 如果price相同，比较hindex
            }
        });
        recommendList.add(ruleRecommendList);


//            基于内容的推荐
        ArrayList<Recommendationcontact> list = recommendationcontactMapper.getListForRecommend();
        recommend recommends = new recommend(list,userType);
        Map<Long,Double> map = recommends.userBasedRecommendForStudent(id);
        for (Map.Entry<Long,Double> entry : map.entrySet()){
            Student student = studentMapper.findById(entry.getKey());
            String name = studentMapper.getNameById(entry.getKey());
            student.setSimilarity(entry.getValue());
            student.setName(name);
            userRecommendList.add(student);
        }
        userRecommendList.sort((i1, i2) -> {
            int priceComparison = Double.compare(i2.getSimilarity(), i1.getSimilarity());
            if (priceComparison != 0) {
                return priceComparison; // 如果price不同，直接返回price的比较结果
            } else {
                return Long.compare(i1.getRank(), i2.getRank()); // 如果price相同，比较hindex
            }
        });
        recommendList.add(userRecommendList);
        return recommendList;
    }

}
